#include "container.h"
#include "../SurfaceFunctions/surfacefunctions.h"
#include "../TextureFunctions/texturefunctions.h"
#include "../DataTypes/datatypes.h"
#include "../GlobalVars/vars.h"
#include <iostream>
#include <fstream>
#include <iomanip>
#include <algorithm>
#include <iterator>
using namespace std;

using namespace std;

const int laenge = 1;
const int breite = 44;

static  datatypes::Vector3D wandConVertices[(laenge+1)*(breite+1)];
static  unsigned int        wandConIndices[(laenge+1)*(breite+1)*6];
static  datatypes::Vector2D wandConTex[(laenge+1)*(breite+1)];
static const   datatypes::Vector3D wandConNormals[(laenge+1)*(breite+1)] = { -0.0290335, 0.998752, -0.0406469, -0.203912, 0.978777, -0.0203912, -0.529999, 0.847998, 0, 0.529999, 0.847998, 0, 0, 1, 0, -0.529999, 0.847998, 0, 0.529999, 0.847998, 0, 0, 1, 0, -0.529999, 0.847998, 0, 0.529999, 0.847998, 0, 0, 1, 0, -0.529999, 0.847998, 0, 0.529999, 0.847998, 0, 0, 1, 0, -0.529999, 0.847998, 0, 0.529999, 0.847998, 0, 0, 1, 0, -0.529999, 0.847998, 0, 0.529999, 0.847998, 0, 0, 1, 0, -0.529999, 0.847998, 0, 0.529999, 0.847998, 0, 0, 1, 0, -0.529999, 0.847998, 0, 0.529999, 0.847998, 0, 0, 1, 0, -0.529999, 0.847998, 0, 0.529999, 0.847998, 0, 0, 1, 0, -0.529999, 0.847998, 0, 0.529999, 0.847998, 0, 0, 1, 0, -0.529999, 0.847998, 0, 0.529999, 0.847998, 0, 0, 1, 0, -0.529999, 0.847998, 0, 0.529999, 0.847998, 0, 0, 1, 0, -0.529999, 0.847998, 0, 0.529999, 0.847998, 0, 0.203912, 0.978777, 0.0203912, -0.639857, 0.767828, 0.0319928, 0.529999, 0.847998, 0, 0, 1, 0, 0.0143663, 0.999897, 0,-0.0290335, 0.998752, -0.0406469, -0.203912, 0.978777, -0.0203912, -0.529999, 0.847998, 0, 0.529999, 0.847998, 0, 0, 1, 0, -0.529999, 0.847998, 0, 0.529999, 0.847998, 0, 0, 1, 0, -0.529999, 0.847998, 0, 0.529999, 0.847998, 0, 0, 1, 0, -0.529999, 0.847998, 0, 0.529999, 0.847998, 0, 0, 1, 0, -0.529999, 0.847998, 0, 0.529999, 0.847998, 0, 0, 1, 0, -0.529999, 0.847998, 0, 0.529999, 0.847998, 0, 0, 1, 0, -0.529999, 0.847998, 0, 0.529999, 0.847998, 0, 0, 1, 0, -0.529999, 0.847998, 0, 0.529999, 0.847998, 0, 0, 1, 0, -0.529999, 0.847998, 0, 0.529999, 0.847998, 0, 0, 1, 0, -0.529999, 0.847998, 0, 0.529999, 0.847998, 0, 0, 1, 0, -0.529999, 0.847998, 0, 0.529999, 0.847998, 0, 0, 1, 0, -0.529999, 0.847998, 0, 0.529999, 0.847998, 0, 0, 1, 0, -0.529999, 0.847998, 0, 0.529999, 0.847998, 0, 0.203912, 0.978777, 0.0203912, -0.639857, 0.767828, 0.0319928, 0.529999, 0.847998, 0, 0, 1, 0, 0.0143663, 0.999897, 0 };

static  datatypes::Vector3D wandConVerticesBack[(laenge+1)*(breite+1)];
static  unsigned int        wandConIndicesBack[(laenge+1)*(breite+1)*6];
static  datatypes::Vector2D wandConTex1[(laenge+1)*(breite+1)];
static  const datatypes::Vector3D wandConNormalsBack[(laenge+1)*(breite+1)] = {0.0290335, -0.998752, 0.0406469, 0.203912, -0.978777, -0.0203912, -0.529999, -0.847998, 0, -0.529999, -0.847998, 0, 0, -1, 0, 0.529999, -0.847998, 0, -0.529999, -0.847998, 0, 0, -1, 0, 0.529999, -0.847998, 0, -0.529999, -0.847998, 0, 0, -1, 0, 0.529999, -0.847998, 0, -0.529999, -0.847998, 0, 0, -1, 0, 0.529999, -0.847998, 0, -0.529999, -0.847998, 0, 0, -1, 0, 0.529999, -0.847998, 0, -0.529999, -0.847998, 0, 0, -1, 0, 0.529999, -0.847998, 0, -0.529999, -0.847998, 0, 0, -1, 0, 0.529999, -0.847998, 0, -0.529999, -0.847998, 0, 0, -1, 0, 0.529999, -0.847998, 0, -0.529999, -0.847998, 0, 0, -1, 0, 0.529999, -0.847998, 0, -0.529999, -0.847998, 0, 0, -1, 0, 0.529999, -0.847998, 0, -0.529999, -0.847998, 0, 0, -1, 0, 0.529999, -0.847998, 0, -0.529999, -0.847998, 0, 0, -1, 0, 0.529999, -0.847998, 0, -0.529999, -0.847998, 0, -0.203912, -0.978777, -0.0203912, 0.639857, -0.767828, -0.0319928, -0.529999, -0.847998, 0, 0, -1, 0, -0.0143663, -0.999897, 0,0.0290335, -0.998752, 0.0406469, 0.203912, -0.978777, 0.0203912, 0.529999, -0.847998, 0, -0.529999, -0.847998, 0, 0, -1, 0, 0.529999, -0.847998, 0, -0.529999, -0.847998, 0, 0, -1, 0, 0.529999, -0.847998, 0, -0.529999, -0.847998, 0, 0, -1, 0, 0.529999, -0.847998, 0, -0.529999, -0.847998, 0, 0, -1, 0, 0.529999, -0.847998, 0, -0.529999, -0.847998, 0, 0, -1, 0, 0.529999, -0.847998, 0, -0.529999, -0.847998, 0, 0, -1, 0, 0.529999, -0.847998, 0, -0.529999, -0.847998, 0, 0, -1, 0, 0.529999, -0.847998, 0, -0.529999, -0.847998, 0, 0, -1, 0, 0.529999, -0.847998, 0, -0.529999, -0.847998, 0, 0, -1, 0, 0.529999, -0.847998, 0, -0.529999, -0.847998, 0, 0, -1, 0, 0.529999, -0.847998, 0, -0.529999, -0.847998, 0, 0, -1, 0, 0.529999, -0.847998, 0, -0.529999, -0.847998, 0, 0, -1, 0, 0.529999, -0.847998, 0, -0.529999, -0.847998, 0, -0.203912, -0.978777, -0.0203912, 0.639857, -0.767828, -0.0319928, -0.529999, -0.847998, 0, 0, -1, 0, -0.0143663, -0.999897 };


const int bodenLaenge = 1;
const int bodenBreite = 1;
static  datatypes::Vector3D bodenVertices[(bodenLaenge+1)*(bodenBreite+1)];
static datatypes::Vector2D bodenTex[(bodenLaenge+1)*(bodenBreite+1)] = { {0,0},{1,0},{0,1},{1,1} };
static  unsigned int        bodenIndices[(bodenLaenge+1)*(bodenBreite+1)*6];
static  const datatypes::Vector3D bodenNormals[(bodenLaenge+1)*(bodenBreite+1)] = { 0,1,0,0,1,0,0,1,0,0,1,0 };
static  const datatypes::Vector3D bodenNormals1[(bodenLaenge+1)*(bodenBreite+1)] = { 0,-1,0,0,-1,0,0,-1,0,0,-1,0 };
									  

static  datatypes::Vector3D bodenVerticesBack[(bodenLaenge+1)*(bodenBreite+1)];
static  unsigned int        bodenIndicesBack[(bodenLaenge+1)*(bodenBreite+1)*6];
static  datatypes::Vector3D bodenNormalsBack[(bodenLaenge+1)*(bodenBreite+1)];

const int deckeLaenge = 10;
const int deckeBreite = 44;
static  datatypes::Vector3D deckeVertices[(deckeLaenge+1)*(deckeBreite+1)];
static  unsigned int        deckeIndices[(deckeLaenge+1)*(deckeBreite+1)*6];


static  datatypes::Vector3D deckeVerticesBack[(deckeLaenge+1)*(deckeBreite+1)];
static  unsigned int        deckeIndicesBack[(deckeLaenge+1)*(deckeBreite+1)*6];
static  datatypes::Vector3D deckeNormalsBack[(deckeLaenge+1)*(deckeBreite+1)];



void init_container()
{
   surfacefunctions::generateSurface(laenge,breite,0.4,8.0,wandConVertices,wandConIndices);
   surfacefunctions::generateSurface(laenge,breite,0.4,8.0,wandConVerticesBack,wandConIndicesBack);
   surfacefunctions::generateSurface(bodenLaenge,bodenBreite,5.0,8.0,bodenVertices,bodenIndices);
   surfacefunctions::generateSurface(bodenLaenge,bodenBreite,5.0,8.0,bodenVerticesBack,bodenIndicesBack);
   surfacefunctions::generateSurface(deckeLaenge,deckeBreite,0.4,0.6,deckeVertices,deckeIndices);
   surfacefunctions::generateSurface(deckeLaenge,deckeBreite,0.4,0.6,deckeVerticesBack,deckeIndicesBack);
   surfacefunctions::computeNormals(deckeLaenge,deckeBreite,deckeVerticesBack,deckeIndicesBack,deckeNormalsBack);

    for(int i=0;i<(laenge+1)*(breite+1);i++)
    {
      if(i%3==0 )
	   {
	    
	     wandConVertices[i].y+=0.5;
	     wandConVertices[i-1].y+=0.5;
	     
	     wandConVerticesBack[i].y-=0.5;
	     wandConVerticesBack[i-1].y-=0.5;
	   }
    }
   wandConVertices[0].y-=0.5;
   wandConVertices[breite+1].y-=0.5;
   wandConVertices[laenge*breite].y-=0.5;
   wandConVerticesBack[0].y+=0.5;
   wandConVerticesBack[breite+1].y+=0.5;
   wandConVerticesBack[laenge*breite].y+=0.5;

   //Generiere Texturekoordinaten
   float tex_breite = (float)laenge/((float)breite);
   int k = 0;
   for(int i=0;i<laenge+1;i++)
    {
	for(int j=0;j<breite+1;j++)
	{
	  wandConTex[k/*i*breite+j*/].x = j*tex_breite;
	  wandConTex[k/*i*breite+j*/].y = i;		
	  k++;
	}
    }
  



}

void draw_normals(int l, int w, const datatypes::Vector3D *ver, const datatypes::Vector3D *norm)
{
  glColor3f(1,0,0);
  glBegin(GL_LINES);
  for(int i=0;i<(l+1)*(w+1);i++)
    {
      glVertex3f(ver[i].x, ver[i].y, ver[i].z);
      glVertex3f(ver[i].x+norm[i].x, ver[i].y+norm[i].y, ver[i].z+norm[i].z);
      
    }
  glEnd();

}

void draw_container(const RGBImage *imgFront, const RGBImage *imgBack)
{
  glDisable(GL_CULL_FACE);
  glPushMatrix();
 
  glEnableClientState(GL_VERTEX_ARRAY);
  glEnableClientState(GL_INDEX_ARRAY);
  glEnableClientState(GL_NORMAL_ARRAY);
  glEnableClientState(GL_TEXTURE_COORD_ARRAY);

  OGL_Set_Current_Material_Parameters(32.0000f, 1.00000f, 1.00000f, 1.00000f, 1.00000f, 1.00000f, 1.00000f);
  OGL_Set_Current_Texture_Map(imgBack,0,0,0,0);

  //Wand 1
  glTexCoordPointer(2,GL_FLOAT,0,wandConTex);
  glNormalPointer(GL_FLOAT,0,wandConNormals);
  glVertexPointer(3,GL_FLOAT,0,wandConVertices);
  /*for(int i=0;i<(laenge+1)*(breite+1)*6;i++)
    glDrawElements(GL_TRIANGLES,3,GL_UNSIGNED_INT, &wandConIndices[i]);*/
  glDrawElements(GL_TRIANGLES,(laenge+1)*(breite+1)*6,GL_UNSIGNED_INT,wandConIndices);
  //draw_normals(laenge,breite,wandConVertices,wandConNormals);
  //Wand 2 verschoben
  

  OGL_Set_Current_Texture_Map(imgFront,0,0,0,0);
  glPushMatrix();
  glTranslatef(0,-5,0);
  glTexCoordPointer(2,GL_FLOAT,0,wandConTex);
  glNormalPointer(GL_FLOAT,0,wandConNormalsBack);
  glVertexPointer(3,GL_FLOAT,0,wandConVerticesBack);
  /*for(int i=0;i<(laenge+1)*(breite+1)*6;i++)
    glDrawElements(GL_TRIANGLES,3,GL_UNSIGNED_INT, &wandConIndicesBack[i]);*/
  glDrawElements(GL_TRIANGLES,(laenge+1)*(breite+1)*6,GL_UNSIGNED_INT,wandConIndicesBack);  
//draw_normals(laenge,breite,wandConVerticesBack,wandConNormalsBack);
  glPopMatrix();
  glDisableClientState(GL_TEXTURE_COORD_ARRAY);

  // linke Tuer
  glPushMatrix();
  glTranslatef(0.4,-10,0);
  glRotatef(90,0,0,1);
  glTexCoordPointer(GL_FLOAT,2,0,bodenTex);
  glNormalPointer(GL_FLOAT,0,bodenNormals);
  glVertexPointer(3,GL_FLOAT,0,bodenVertices);
  OGL_Set_Current_Texture_Map(imgBack,0,0,0,0);

  /*  for(int i=0;i<(bodenLaenge+1)*(bodenBreite+1)*6;i++)
    glDrawElements(GL_TRIANGLES,3,GL_UNSIGNED_INT, &bodenIndices[i]);*/

  glDrawElements(GL_TRIANGLES,(bodenLaenge+1)*(bodenBreite+1)*6,GL_UNSIGNED_INT,bodenIndices);
  //draw_normals(bodenLaenge,bodenBreite,bodenVertices,bodenNormals);
   
  // rechte Tuer

  glTranslatef(0,-17.6,0);
  glNormalPointer(GL_FLOAT,0,bodenNormals1);
  glVertexPointer(3,GL_FLOAT,0,bodenVertices);
  glDrawElements(GL_TRIANGLES,(bodenLaenge+1)*(bodenBreite+1)*6,GL_UNSIGNED_INT,bodenIndices);
  //draw_normals(bodenLaenge,bodenBreite,bodenVertices,bodenNormals1);
  glPopMatrix();

  
  glDisableClientState(GL_NORMAL_ARRAY); // Boden ohne Normalen malen
  glPushMatrix();
  glTranslatef(0.0,0.5,0.0);
  glRotatef(90,1,0,0);
  glTexCoordPointer(GL_FLOAT,2,0,wandConTex);
  glVertexPointer(3,GL_FLOAT,0,deckeVertices);
  glDrawElements(GL_TRIANGLES,(deckeLaenge+1)*(deckeBreite+1)*6,GL_UNSIGNED_INT,deckeIndices);

  glEnable(GL_NORMAL_ARRAY);
  glPushMatrix();
  glTranslatef(0,8,0);
  glNormalPointer(GL_FLOAT,0,deckeNormalsBack);
  glVertexPointer(3,GL_FLOAT,0,deckeVerticesBack);
  glDrawElements(GL_TRIANGLES,(deckeLaenge+1)*(deckeBreite+1)*6,GL_UNSIGNED_INT,deckeIndicesBack);
  //draw_normals(deckeLaenge,deckeBreite,deckeVertices,deckeNormalsBack);

  glPopMatrix();
  glPopMatrix();

  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  glDisableClientState(GL_INDEX_ARRAY);
  glDisableClientState(GL_VERTEX_ARRAY);
  glDisableClientState(GL_NORMAL_ARRAY);
 
  glPopMatrix();
  glEnable(GL_CULL_FACE);
}
